/**
* @project admin-go-api
* @name jwt
* @descriptions JWT工具类(生成token,解析token,获取当前登录的用户id及用户信息)
* @author 寒锋
* @date 2023-12-14 16:11:28
 */

package jwt

import (
	"admin-go-api/api/entity"
	"admin-go-api/constants"
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"time"
)

type userStdClaims struct {
	entity.JwtAdmin
	jwt.StandardClaims
}

// TokenExpireDuration token过期时间
const TokenExpireDuration = time.Hour * 24

// SecretKey token密钥
var SecretKey = []byte("admin-go-api")

var (
	ErrAbsent  = "token absent"  // 令牌不存在
	ErrInvalid = "token invalid" // 令牌无效
)

// GenerateTokenByAdmin 根据用户信息生成token
func GenerateTokenByAdmin(admin entity.SysAdmin) (string, error) {
	var jwtAdmin = entity.JwtAdmin{
		AdminId:      admin.AdminId,
		Username:     admin.Username,
		Nickname:     admin.Nickname,
		ProfilePhoto: admin.ProfilePhoto,
		Email:        admin.Email, Phone: admin.Phone,
		Note: admin.Note,
	}
	c := userStdClaims{
		jwtAdmin,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
			Issuer:    "admin-go-api",                             // 签发人
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	return token.SignedString(SecretKey)
}

// ValidateToken 解析JWT
func ValidateToken(tokenString string) (*entity.JwtAdmin, error) {
	if tokenString == "" {
		return nil, errors.New(ErrAbsent)
	}
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return SecretKey, nil
	})
	if token == nil {
		return nil, errors.New(ErrInvalid)
	}
	claims := userStdClaims{}
	_, err = jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}
		return SecretKey, nil
	})
	if err != nil {
		return nil, err
	}
	return &claims.JwtAdmin, err
}

// GetAdminId 返回管理员id
func GetAdminId(c *gin.Context) (uint, error) {
	admin, err := GetAdmin(c)
	if err != nil {
		return 0, err
	}
	return admin.AdminId, nil
	// u, exists := c.Get(constants.ContextKeyUserObj)
	// if !exists {
	// 	return 0, errors.New("没有找到管理员信息")
	// }
	// admin, ok := u.(*entity.JwtAdmin)
	// if ok {
	// 	return admin.AdminId, nil
	// }
	// return 0, errors.New("不能转换为id结构")
}

// GetAdminUserName 返回管理员用户名
func GetAdminUserName(c *gin.Context) (string, error) {
	admin, err := GetAdmin(c)
	if err != nil {
		return "", err
	}
	return admin.Username, nil
	// u, exists := c.Get(constants.ContextKeyUserObj)
	// if !exists {
	// 	return string(string(0)), errors.New("没有找到管理员信息")
	// }
	// admin, ok := u.(*entity.JwtAdmin)
	// if ok {
	// 	return admin.Username, nil
	// }
	// return string(string(0)), errors.New("不能转换为用户结构")
}

// GetAdmin 获取管理员信息
func GetAdmin(c *gin.Context) (*entity.JwtAdmin, error) {
	u, exists := c.Get(constants.ContextKeyUserObj)
	if !exists {
		return nil, errors.New("没有找到管理员信息")
	}
	admin, ok := u.(*entity.JwtAdmin)
	if ok {
		return admin, nil
	}
	return nil, errors.New("不能转换为正确结构")
}
